package com.tax.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tax.common.constant.CommonHeader;
import com.tax.common.constant.RequestHolderUtil;
import com.tax.common.util.DateUtil;
import com.tax.common.util.HashUtil;
import com.tax.config.exception.ApiException;
import com.tax.config.jwt.JwtUserInfo;
import com.tax.config.page.PageResult;
import com.tax.config.response.Response;
import com.tax.config.response.ResponseCode;
import com.tax.dto.req.*;
import com.tax.dto.res.LoginRes;
import com.tax.dto.res.UserInfoRes;
import com.tax.dto.res.UserPageInfo;
import com.tax.entity.TdUser;
import com.tax.enums.StateEnum;
import com.tax.manager.AccessTokenManager;
import com.tax.mapper.TdUserMapper;
import com.tax.service.ISmsService;
import com.tax.service.ITdUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author ddh142782（段德辉）
 * @since 2023-03-04
 */
@Slf4j
@Service("iTdUserService")
public class TdUserServiceImpl extends ServiceImpl<TdUserMapper, TdUser> implements ITdUserService {


    @Autowired
    private TdUserMapper tdUserMapper;

    @Autowired
    private AccessTokenManager accessTokenManager;

    @Autowired
    private ISmsService smsService;
    @Override
    public UserInfoRes getUserInfo(UserInfoReq req) {
        QueryWrapper<TdUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",req.getUserId());
        TdUser tdUser = tdUserMapper.selectOne(wrapper);
        if (null==tdUser){
            return null;
        }
        UserInfoRes res=new UserInfoRes();
        BeanUtils.copyProperties(tdUser,res);
        res.setRegisterTime(tdUser.getCreatedDate());
        return res;
    }

    @Override
    public TdUser selectUserByPhone(String phone) {
        if (StringUtils.isBlank(phone)){
            return null;
        }
        QueryWrapper<TdUser> wrapper = new QueryWrapper<>();
        wrapper.eq("telephone",phone);
        wrapper.last(" limit 1");
        return tdUserMapper.selectOne(wrapper);
    }

    @Override
    public PageResult<UserPageInfo> userPage(UserPageReq req) {
        QueryWrapper<TdUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(req.getTelephone())){
            wrapper.like("telephone",req.getTelephone());
        }
        if (null!=req.getState()){
            wrapper.eq("state",req.getState());
        }
        if (StringUtils.isNotBlank(req.getStartTime())){
            wrapper.ge("created_date",req.getStartTime());
        }
        if (StringUtils.isNotBlank(req.getEndTime())){
            wrapper.lt("created_date",req.getEndTime());
        }
        Page<TdUser> page=new Page<>(req.getPageNo(),req.getPageSize());
        Page<TdUser> tdUserPage = tdUserMapper.selectPage(page,wrapper);
        List<TdUser> tdUsers = tdUserPage.getRecords();
        List<UserPageInfo> userPageInfoList=new ArrayList<>();
        if (!CollectionUtils.isEmpty(tdUsers)){
            tdUsers.forEach(l->{
                UserPageInfo info=new UserPageInfo();
                BeanUtils.copyProperties(l,info);
                info.setGenerateReportNum(0);
                userPageInfoList.add(info);
            });
        }
        PageResult<UserPageInfo> result=new PageResult();
        result.load(tdUserPage);
        result.setResultList(userPageInfoList);
        return result;
    }

    @Override
    public Response<JwtUserInfo> v2jwtUserInfo(TokenReq req) {
        JwtUserInfo jwtUserInfo = accessTokenManager.getJwtUserInfo(req.getToken());
        if(jwtUserInfo==null){
            return new Response<>(ResponseCode.TOKEN_INVAILD_ERROR.getCode(), ResponseCode.TOKEN_INVAILD_ERROR.getMsg());
        }
        return new Response<>(jwtUserInfo);
    }

    @Override
    public LoginRes appLogin(LoginReq req)  throws ApiException {
        //1.检验验证码是否正确
        String phoneNum = req.getTelephone();
        String regCode = req.getRegCode();
        smsService.verifyRegCode(regCode, phoneNum);
        //2.判断用户是否存在，如果不存在，则初始化一个用户
        CommonHeader commonHeader = RequestHolderUtil.getCommonHeader();
        TdUser tdUser = selectUserByPhone(phoneNum);
        if (tdUser == null) {
            tdUser = createUser(phoneNum);
            log.info("login,新用户注册");
        }
        String deviceId = commonHeader.getDeviceId();
        String appVersion = commonHeader.getAppVersion();
        String appsys = commonHeader.getAppsys();
        //3.给用户生成token
        String generateToken = accessTokenManager.generateToken(tdUser, deviceId, appsys, appVersion);
        log.info("login,用户登录,generateToken:{}",generateToken);
        LoginRes loginRes = new LoginRes();
        loginRes.setToken(generateToken);
        loginRes.setTelephone(phoneNum);
        loginRes.setUserId(tdUser.getUserId());
        //4.将用户的token放在缓存中
        smsService.removeRegCode(phoneNum);
        accessTokenManager.cacheLoginToken(phoneNum,generateToken);
        return loginRes;
    }

    @Override
    public UserInfoRes editPassword(EditPasswordReq req) throws ApiException {
        String newPassword = req.getNewPassword();//新密码
        String oldPassword = req.getOldPassword();//旧密码
        String userId = req.getUserId();
        TdUser tdUser = findByUserId(userId);
        if (null==tdUser){
            throw new ApiException("用户信息不存在");
        }
        //盐值
        String pwSalt =tdUser.getPasswordSalt();
        //根据旧密码获取到加密的密码
        String password = HashUtil.strHash_MD5(HashUtil.strHash_MD5(oldPassword) + pwSalt);
        String passwordHash = tdUser.getPassword();
        //比较旧密码和数据库密码,看是否相同
        if (!password.equals(passwordHash)) {
            log.warn("原密码不正确");
            throw new ApiException("原密码不正确");
        }
        String newpassword = HashUtil.strHash_MD5(HashUtil.strHash_MD5(newPassword) + pwSalt);
        tdUser.setPassword(newpassword);
        tdUserMapper.updateById(tdUser);
        UserInfoRes res=new UserInfoRes();
        BeanUtils.copyProperties(tdUser,res);
        res.setRegisterTime(tdUser.getCreatedDate());
        return res;
    }

    @Override
    public TdUser createUser(String phoneNum) {
        Date curDate = new Date();
        TdUser tblUser = new TdUser();
        String userId = RandomStringUtils.randomAlphanumeric(20);
        TdUser oldUser = findByUserId(userId);
        if(oldUser!=null){
            userId = RandomStringUtils.randomAlphanumeric(20);
        }
        //初始化密码为123456
        String pwSalt = HashUtil.getRandomId();
        String password = HashUtil.strHash_MD5(HashUtil.strHash_MD5("123456") + pwSalt);
        String dateStr = DateUtil.parseDateToString(curDate, DateUtil.PATTERN_yyyy_MM_dd_HHmmss);
        tblUser.setUserId(userId);
        tblUser.setTelephone(phoneNum);
        tblUser.setState(StateEnum.NORMAL.getCode());
        tblUser.setPassword(password);
        tblUser.setPasswordSalt(pwSalt);
        tblUser.setCreatedDate(dateStr);
        tblUser.setUpdatedDate(dateStr);
        tblUser.setCreatedBy("-1");
        tblUser.setUpdatedBy("-1");
        tdUserMapper.insert(tblUser);
        return tblUser;
    }

    private TdUser findByUserId(String userId) {
        if (StringUtils.isBlank(userId)){
            return null;
        }
        QueryWrapper<TdUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        wrapper.last(" limit 1");
        return tdUserMapper.selectOne(wrapper);
    }
}
